import java.util.concurrent.PriorityBlockingQueue;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-03-23
 * Time: 15:28
 */
//自己实现一个定时器

//表示一个执行的任务
class MyTask implements Comparable<MyTask>{//实现堆就要写比较规则,根据啥比较的
    public Runnable runnable;//这里是runnable类型的是因为根据源码写的
    public long time;//任务执行的绝对时间

    public MyTask(Runnable runnable,long delay){
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+delay;//绝对时间戳=(当前时间-基准时间)+任务多久后执行的时间
    }

    @Override
    public int compareTo(MyTask o) {
        return (int)(this.time-o.time);
    }
}
class MyTimer{
    //创建带有阻塞功能的优先级阻塞队列

   private Object locker=new Object();

    private PriorityBlockingQueue<MyTask> queue=new PriorityBlockingQueue<>();
   public void schedule(Runnable runnable,long delay){
       //根据参数,构造任务,插入队列中
       MyTask myTask=new MyTask(runnable,delay);
       queue.put(myTask);

        synchronized (locker){
           locker.notify();
       }

   }
   //构造线程,执行具体任务

    public MyTimer(){
       Thread t=new Thread(()->{
           while(true){
               try {
                   synchronized (locker) {
                   MyTask myTask= queue.take();

                   long curTime=System.currentTimeMillis();
                   if (myTask.time <= curTime) {
                            //时间到了,执行该任务
                       myTask.runnable.run();

                   }else {
                       //时间还没到,所以需要将拿出的队列放回去
                       queue.put(myTask);

                           locker.wait(myTask.time - curTime);
                       }
                   }



               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }

           }
       });
       t.start();
    }

}

public class ThreadDemo4 {
    public static void main(String[] args) {
        MyTimer myTimer=new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 4");
            }
        },4000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3");
            }
        },3000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2");
            }
        },2000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1");
            }
        },1000);

    }


}
